﻿/**
 * 基于硬件的定时器,依赖中断,无需轮询
 * @author Zr
 */
#pragma once
#include <xscugic.h>
#include <xscutimer.h>

#include <functional>
#include <map>
#include <string>

#include "ZTimerCommon.h"

class ZTimerHW {
  // 单个任务
  struct TaskInternal {
    // 任务名称
    std::string name{};
    // 任务回调函数
    std::function<void()> callback{nullptr};
    // 任务周期,单位ms
    unsigned long period{1000};
    // 过去的时间,单位ms
    unsigned elapsedTime{0};
  };
public:
  /**
   * @param period 基础的计时的周期,单位ms
   * @param cpuFreq cpu的主频,单位Hz
   */
  explicit ZTimerHW(int period = 1, unsigned cpuFreq = 666.66 * 1000000);

  /**
   * 添加一个任务,任务名要求唯一
   * @param task 任务
   */
  void add(Task task);

  /**
   * 删除1个任务
   * @param taskName 任务名称
   */
  void remove(const std::string &taskName);

private:
  /**
   * 初始化
   */
  void initialize();

  /**
   * 初始化定时器
   */
  void initTimer();

  /**
   * 初始化定时器中断
   */
  void initInterrupt();

  /**
   * 基础定时器触发的函数
   * @param that 自身指针
   */
  static void baseCallbackFunc(void *that);

private:
  // 定时器中断回调函数
  std::map<std::string, TaskInternal> callbacks_;

  // 定时的周期,单位ms
  int period_;
  // cpu的主频,单位Hz
  unsigned cpuFreq_;
  // 定时器装载值
  unsigned timerLoadValue_;
  // 定时器指针
  XScuTimer timer_;
  // 中断控制器指针
  XScuGic intc_;
};